package whu.cn.whushare.db;

import java.sql.SQLException;
import java.util.List;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import whu.cn.whushare.bean.User;

import com.j256.ormlite.android.apptools.OpenHelperManager;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.stmt.DeleteBuilder;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.UpdateBuilder;

public class DBInstance {
	private static final String TAG = "DBInstance";

	private static DBInstance INSTANCE;
	private Context mContext;

	private Dao<User, Integer> mUserDao;
	private DbHelper mDbHelper;

	private final Object mDBLock = new Object();

	private DBInstance(Context context) {
		mContext = context.getApplicationContext();
	}

	public synchronized static DBInstance getInstance(Context context) {
		if (INSTANCE == null) {
			INSTANCE = new DBInstance(context);//实例化对象
		}
		return INSTANCE;
	}

	private synchronized void registerUserDB() throws SQLException {
		mDbHelper = OpenHelperManager.getHelper(mContext, DbHelper.class);//获取对象
		mUserDao = mDbHelper.getUserDao();
	}

	private synchronized void closeMainDB() {
		mUserDao = null;
		mDbHelper.close();
		mDbHelper = null;
		OpenHelperManager.releaseHelper();
		DaoManager.clearCache();
	}

	@SuppressWarnings("unused")
	public boolean loginAccount(User user) {
		synchronized (mDBLock) {
			SQLiteDatabase sqliteDatabase = null;
			boolean result;
			try {
				registerUserDB();
				sqliteDatabase = mDbHelper.getWritableDatabase();
				sqliteDatabase.beginTransaction();

				QueryBuilder<User, Integer> queryBuilder = mUserDao.queryBuilder();
				queryBuilder.where().eq(User.USER_ID, user.getId());
				User dbUser = queryBuilder.queryForFirst();//queryForFirst(),返回第一条匹配的结果
				if (dbUser == null) {
					result = (mUserDao.create(user) == 1);
				} else {
					UpdateBuilder<User, Integer> updateBuilder = mUserDao.updateBuilder();
					updateBuilder.updateColumnValue(User.TOKEN, user.getToken());//根据特定条件更新特定字段
					setUserUpdateBuilder(user, updateBuilder);
					updateBuilder.where().eq(User.USER_ID, user.getId());
					result = (updateBuilder.update() > 0);
				}

				sqliteDatabase.setTransactionSuccessful();//setTransactionSuccessful()方法设置事务的标志为成功则提交事务，如果没有调用setTransactionSuccessful()方法则回滚事务

				return result;
			} catch (SQLException e) {
				Log.e(TAG, "loginAccount:" + e.getMessage());
			} finally {
				if (sqliteDatabase != null) {
					sqliteDatabase.endTransaction();
					sqliteDatabase = null;
				}
				closeMainDB();
			}
		}
		return false;
	}

	public boolean deleteUser(long userId) {
		synchronized (mDBLock) {
			try {
				registerUserDB();
				DeleteBuilder<User, Integer> deleteBuilder = mUserDao.deleteBuilder();
				deleteBuilder.where().eq(User.USER_ID, userId);
				return deleteBuilder.delete() > 0;
			} catch (SQLException e) {
				Log.e(TAG, "deleteUser:" + e.getMessage());
			} finally {
				closeMainDB();
			}
		}
		return false;
	}

	public List<User> getAllUser() {
		synchronized (mDBLock) {
			try {
				registerUserDB();
				QueryBuilder<User, Integer> builder = mUserDao.queryBuilder();
				return builder.query();
			} catch (SQLException e) {
				Log.e(TAG, "getAllUser:" + e.getMessage());
			} finally {
				closeMainDB();
			}
		}
		return null;
	}

	public User getCurrentLoginAccount() {
		synchronized (mDBLock) {
			try {
				registerUserDB();
				QueryBuilder<User, Integer> builder = mUserDao.queryBuilder();
				builder.where().eq(User.IS_CURRENT_LOGIN_ACCOUNT, User.IS_CURRENT_LOGIN_ACCOUNT_TRUE);
				return builder.queryForFirst();
			} catch (SQLException e) {
				Log.e(TAG, "getCurrentLoginAccount:" + e.getMessage());
			} finally {
				closeMainDB();
			}
		}
		return null;
	}

	public boolean updateUserInfo(User user) {
		synchronized (mDBLock) {
			try {
				registerUserDB();
				UpdateBuilder<User, Integer> builder = mUserDao.updateBuilder();

				setUserUpdateBuilder(user, builder);
				builder.where().eq(User.USER_ID, user.getId());
				return builder.update() > 0;
			} catch (SQLException e) {
				Log.e(TAG, "updateUserInfo:" + e.getMessage());
			} finally {
				closeMainDB();
			}
		}
		return false;
	}

	private void setUserUpdateBuilder(User user, UpdateBuilder<User, Integer> updateBuilder) throws SQLException {
		updateBuilder.updateColumnValue(User.IS_CURRENT_LOGIN_ACCOUNT, user.getIsCurrentLoginAccount());
		updateBuilder.updateColumnValue(User.NICK_NAME, user.getNickName());
		updateBuilder.updateColumnValue(User.AVATAR_INDEX, user.getAvatar());
	}

	public boolean updateNick(String userId, String nick) {
		synchronized (mDBLock) {
			try {
				registerUserDB();
				UpdateBuilder<User, Integer> builder = mUserDao.updateBuilder();
				builder.updateColumnValue(User.NICK_NAME, nick);
				builder.where().eq(User.USER_ID, userId);
				return builder.update() > 0;
			} catch (SQLException e) {
				Log.e(TAG, "updateNick:" + e.getMessage());
			} finally {
				closeMainDB();
			}
		}
		return false;
	}

	public boolean updateAvatarIndex(String userId, int avatarIndex) {
		synchronized (mDBLock) {
			try {
				registerUserDB();
				UpdateBuilder<User, Integer> builder = mUserDao.updateBuilder();
				builder.updateColumnValue(User.AVATAR_INDEX, avatarIndex);
				builder.where().eq(User.USER_ID, userId);
				return builder.update() > 0;
			} catch (SQLException e) {
				Log.e(TAG, "updateAvatarIndex:" + e.getMessage());
			} finally {
				closeMainDB();
			}
		}
		return false;
	}

	public boolean updateToken(String userId, String token) {
		synchronized (mDBLock) {
			try {
				registerUserDB();
				UpdateBuilder<User, Integer> builder = mUserDao.updateBuilder();
				builder.updateColumnValue(User.TOKEN, token);
				builder.where().eq(User.USER_ID, userId);
				return builder.update() > 0;
			} catch (SQLException e) {
				Log.e(TAG, "updateToken:" + e.getMessage());
			} finally {
				closeMainDB();
			}
		}
		return false;
	}

	public boolean updateIsCurrentLoginAccount(String userId, int isCurrentLoginAccount) {
		synchronized (mDBLock) {
			try {
				registerUserDB();
				UpdateBuilder<User, Integer> builder = mUserDao.updateBuilder();
				builder.updateColumnValue(User.IS_CURRENT_LOGIN_ACCOUNT, isCurrentLoginAccount);
				builder.where().eq(User.USER_ID, userId);
				return builder.update() > 0;
			} catch (SQLException e) {
				Log.e(TAG, "updateToken:" + e.getMessage());
			} finally {
				closeMainDB();
			}
		}
		return false;
	}
}
